home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  12.5 KB  |  447 lines

  1. /* $Id: misc.c,v 1.11 1997/02/10 20:40:51 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: misc.c,v $
  26.  * Revision 1.11  1997/02/10 20:40:51  brianp
  27.  * added GL_MESA_resize_buffers to extensions string
  28.  *
  29.  * Revision 1.10  1997/02/09 18:44:35  brianp
  30.  * added GL_EXT_texture3D support
  31.  *
  32.  * Revision 1.9  1997/01/08 20:55:02  brianp
  33.  * added GL_EXT_texture_object
  34.  *
  35.  * Revision 1.8  1996/11/05 01:41:45  brianp
  36.  * fixed potential scissor/clear color buffer bug
  37.  *
  38.  * Revision 1.7  1996/10/30 03:14:02  brianp
  39.  * incremented version to 2.1
  40.  *
  41.  * Revision 1.6  1996/10/11 03:42:17  brianp
  42.  * added GL_EXT_polygon_offset to extensions string
  43.  *
  44.  * Revision 1.5  1996/10/02 02:51:44  brianp
  45.  * created clear_color_buffers() which handles draw mode GL_FRONT_AND_BACK
  46.  *
  47.  * Revision 1.4  1996/09/25 03:22:14  brianp
  48.  * glDrawBuffer(GL_NONE) works now
  49.  *
  50.  * Revision 1.3  1996/09/24 00:16:10  brianp
  51.  * set NewState flag in glRead/DrawBuffer() and glHint()
  52.  * fixed display list bug in gl_Hint()
  53.  *
  54.  * Revision 1.2  1996/09/15 14:18:37  brianp
  55.  * now use GLframebuffer and GLvisual
  56.  *
  57.  * Revision 1.1  1996/09/13 01:38:16  brianp
  58.  * Initial revision
  59.  *
  60.  */
  61.  
  62.  
  63. #include <stdlib.h>
  64. #include <string.h>
  65. #include "accum.h"
  66. #include "alphabuf.h"
  67. #include "context.h"
  68. #include "depth.h"
  69. #include "macros.h"
  70. #include "masking.h"
  71. #include "misc.h"
  72. #include "stencil.h"
  73. #include "types.h"
  74.  
  75.  
  76.  
  77.  
  78.  
  79. void gl_ClearIndex( GLcontext *ctx, GLfloat c )
  80. {
  81.    if (INSIDE_BEGIN_END(ctx)) {
  82.       gl_error( ctx, GL_INVALID_OPERATION, "glClearIndex" );
  83.       return;
  84.    }
  85.    ctx->Color.ClearIndex = (GLuint) c;
  86.    if (!ctx->Visual->RGBAflag) {
  87.       /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
  88.       (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex );
  89.    }
  90. }
  91.  
  92.  
  93.  
  94. void gl_ClearColor( GLcontext *ctx, GLclampf red, GLclampf green,
  95.                     GLclampf blue, GLclampf alpha )
  96. {
  97.    if (INSIDE_BEGIN_END(ctx)) {
  98.       gl_error( ctx, GL_INVALID_OPERATION, "glClearColor" );
  99.       return;
  100.    }
  101.  
  102.    ctx->Color.ClearColor[0] = CLAMP( red,   0.0F, 1.0F );
  103.    ctx->Color.ClearColor[1] = CLAMP( green, 0.0F, 1.0F );
  104.    ctx->Color.ClearColor[2] = CLAMP( blue,  0.0F, 1.0F );
  105.    ctx->Color.ClearColor[3] = CLAMP( alpha, 0.0F, 1.0F );
  106.  
  107.    if (ctx->Visual->RGBAflag) {
  108.       GLubyte r = (GLint) (ctx->Color.ClearColor[0] * ctx->Visual->RedScale);
  109.       GLubyte g = (GLint) (ctx->Color.ClearColor[1] * ctx->Visual->GreenScale);
  110.       GLubyte b = (GLint) (ctx->Color.ClearColor[2] * ctx->Visual->BlueScale);
  111.       GLubyte a = (GLint) (ctx->Color.ClearColor[3] * ctx->Visual->AlphaScale);
  112.       (*ctx->Driver.ClearColor)( ctx, r, g, b, a );
  113.    }
  114. }
  115.  
  116.  
  117.  
  118.  
  119. /*
  120.  * Clear the color buffer when glColorMask or glIndexMask is in effect.
  121.  */
  122. static void clear_color_buffer_with_masking( GLcontext *ctx )
  123. {
  124.    GLint x, y, height, width;
  125.  
  126.    /* Compute region to clear */
  127.    if (ctx->Scissor.Enabled) {
  128.       x = ctx->Buffer->Xmin;
  129.       y = ctx->Buffer->Ymin;
  130.       height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  131.       width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  132.    }
  133.    else {
  134.       x = 0;
  135.       y = 0;
  136.       height = ctx->Buffer->Height;
  137.       width  = ctx->Buffer->Width;
  138.    }
  139.  
  140.    if (ctx->Visual->RGBAflag) {
  141.       /* RGBA mode */
  142.       GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  143.       GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  144.       GLubyte r = ctx->Color.ClearColor[0] * ctx->Visual->RedScale;
  145.       GLubyte g = ctx->Color.ClearColor[1] * ctx->Visual->GreenScale;
  146.       GLubyte b = ctx->Color.ClearColor[2] * ctx->Visual->BlueScale;
  147.       GLubyte a = ctx->Color.ClearColor[3] * ctx->Visual->AlphaScale;
  148.       GLint i;
  149.       for (i=0;i<height;i++,y++) {
  150.          MEMSET( red,   (int) r, width );
  151.          MEMSET( green, (int) g, width );
  152.          MEMSET( blue,  (int) b, width );
  153.          MEMSET( alpha, (int) a, width );
  154.          gl_mask_color_span( ctx, width, x, y, red, green, blue, alpha );
  155.          (*ctx->Driver.WriteColorSpan)( ctx,
  156.                                  width, x, y, red, green, blue, alpha, NULL );
  157.          if (ctx->RasterMask & ALPHABUF_BIT) {
  158.             gl_write_alpha_span( ctx, width, x, y, alpha, NULL );
  159.          }
  160.       }
  161.    }
  162.    else {
  163.       /* Color index mode */
  164.       GLuint indx[MAX_WIDTH];
  165.       GLubyte mask[MAX_WIDTH];
  166.       GLint i, j;
  167.       MEMSET( mask, 1, width );
  168.       for (i=0;i<height;i++,y++) {
  169.          for (j=0;j<width;j++) {
  170.             indx[j] = ctx->Color.ClearIndex;
  171.          }
  172.          gl_mask_index_span( ctx, width, x, y, indx );
  173.          (*ctx->Driver.WriteIndexSpan)( ctx, width, x, y, indx, mask );
  174.       }
  175.    }
  176. }
  177.  
  178.  
  179.  
  180. /*
  181.  * Clear the front and/or back color buffers.  Also clear the alpha
  182.  * buffer(s) if present.
  183.  */
  184. static void clear_color_buffers( GLcontext *ctx )
  185. {
  186.    if (ctx->Color.SWmasking) {
  187.       clear_color_buffer_with_masking( ctx );
  188.    }
  189.    else {
  190.       GLint x = ctx->Buffer->Xmin;
  191.       GLint y = ctx->Buffer->Ymin;
  192.       GLint height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  193.       GLint width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  194.       (*ctx->Driver.Clear)( ctx, !ctx->Scissor.Enabled,
  195.                             x, y, width, height );
  196.       if (ctx->RasterMask & ALPHABUF_BIT) {
  197.          /* front and/or back alpha buffers will be cleared here */
  198.          gl_clear_alpha_buffers( ctx );
  199.       }
  200.    }
  201.  
  202.    if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  203.       /*** Also clear the back buffer ***/
  204.       (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  205.       if (ctx->Color.SWmasking) {
  206.          clear_color_buffer_with_masking( ctx );
  207.       }
  208.       else {
  209.          GLint x = ctx->Buffer->Xmin;
  210.          GLint y = ctx->Buffer->Ymin;
  211.          GLint height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  212.          GLint width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  213.          (*ctx->Driver.Clear)( ctx, !ctx->Scissor.Enabled,
  214.                                x, y, width, height );
  215.       }
  216.       (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  217.    }
  218. }
  219.  
  220.  
  221.  
  222. void gl_Clear( GLcontext *ctx, GLbitfield mask )
  223. {
  224. #ifdef PROFILE
  225.    GLdouble t0 = gl_time();
  226. #endif
  227.  
  228.    if (INSIDE_BEGIN_END(ctx)) {
  229.       gl_error( ctx, GL_INVALID_OPERATION, "glClear" );
  230.       return;
  231.    }
  232.  
  233.    if (ctx->NewState) {
  234.       gl_update_state( ctx );
  235.    }
  236.  
  237.    if (mask & GL_COLOR_BUFFER_BIT)   clear_color_buffers( ctx );
  238.    if (mask & GL_DEPTH_BUFFER_BIT)   (*ctx->Driver.ClearDepthBuffer)( ctx );
  239.    if (mask & GL_ACCUM_BUFFER_BIT)   gl_clear_accum_buffer( ctx );
  240.    if (mask & GL_STENCIL_BUFFER_BIT) gl_clear_stencil_buffer( ctx );
  241.  
  242. #ifdef PROFILE
  243.    ctx->ClearTime += gl_time() - t0;
  244.    ctx->ClearCount++;
  245. #endif
  246. }
  247.  
  248.  
  249.  
  250. const GLubyte *gl_GetString( GLcontext *ctx, GLenum name )
  251. {
  252.    static char *vendor = "Brian Paul";
  253.    static char *renderer = "Mesa";
  254.    static char *version = "1.1 Mesa 2.2";
  255.    static char *extensions = "GL_EXT_blend_color GL_EXT_blend_minmax GL_EXT_blend_logic_op GL_EXT_blend_subtract GL_EXT_polygon_offset GL_EXT_vertex_array GL_EXT_texture_object GL_EXT_texture3D GL_MESA_window_pos GL_MESA_resize_buffers";
  256.  
  257.    if (INSIDE_BEGIN_END(ctx)) {
  258.       gl_error( ctx, GL_INVALID_OPERATION, "glGetString" );
  259.       return (GLubyte *) 0;
  260.    }
  261.  
  262.    switch (name) {
  263.       case GL_VENDOR:
  264.          return (GLubyte *) vendor;
  265.       case GL_RENDERER:
  266.          return (GLubyte *) renderer;
  267.       case GL_VERSION:
  268.          return (GLubyte *) version;
  269.       case GL_EXTENSIONS:
  270.          return (GLubyte *) extensions;
  271.       default:
  272.          gl_error( ctx, GL_INVALID_ENUM, "glGetString" );
  273.          return (GLubyte *) 0;
  274.    }
  275. }
  276.  
  277.  
  278.  
  279. void gl_Finish( GLcontext *ctx )
  280. {
  281.    /* Don't compile into display list */
  282.    if (INSIDE_BEGIN_END(ctx)) {
  283.       gl_error( ctx, GL_INVALID_OPERATION, "glFinish" );
  284.       return;
  285.    }
  286.    if (ctx->Driver.Finish) {
  287.       (*ctx->Driver.Finish)( ctx );
  288.    }
  289. }
  290.  
  291.  
  292.  
  293. void gl_Flush( GLcontext *ctx )
  294. {
  295.    /* Don't compile into display list */
  296.    if (INSIDE_BEGIN_END(ctx)) {
  297.       gl_error( ctx, GL_INVALID_OPERATION, "glFlush" );
  298.       return;
  299.    }
  300.    if (ctx->Driver.Flush) {
  301.       (*ctx->Driver.Flush)( ctx );
  302.    }
  303. }
  304.  
  305.  
  306.  
  307. void gl_Hint( GLcontext *ctx, GLenum target, GLenum mode )
  308. {
  309.    if (INSIDE_BEGIN_END(ctx)) {
  310.       gl_error( ctx, GL_INVALID_OPERATION, "glHint" );
  311.       return;
  312.    }
  313.    if (mode!=GL_DONT_CARE && mode!=GL_FASTEST && mode!=GL_NICEST) {
  314.       gl_error( ctx, GL_INVALID_ENUM, "glHint(mode)" );
  315.       return;
  316.    }
  317.    switch (target) {
  318.       case GL_FOG_HINT:
  319.          ctx->Hint.Fog = mode;
  320.          break;
  321.       case GL_LINE_SMOOTH_HINT:
  322.          ctx->Hint.LineSmooth = mode;
  323.          break;
  324.       case GL_PERSPECTIVE_CORRECTION_HINT:
  325.          ctx->Hint.PerspectiveCorrection = mode;
  326.          break;
  327.       case GL_POINT_SMOOTH_HINT:
  328.          ctx->Hint.PointSmooth = mode;
  329.          break;
  330.       case GL_POLYGON_SMOOTH_HINT:
  331.          ctx->Hint.PolygonSmooth = mode;
  332.          break;
  333.       default:
  334.          gl_error( ctx, GL_INVALID_ENUM, "glHint(target)" );
  335.    }
  336.    ctx->NewState |= NEW_ALL;   /* just to be safe */
  337. }
  338.  
  339.  
  340.  
  341. void gl_DrawBuffer( GLcontext *ctx, GLenum mode )
  342. {
  343.    if (INSIDE_BEGIN_END(ctx)) {
  344.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  345.       return;
  346.    }
  347.    switch (mode) {
  348.       case GL_FRONT:
  349.       case GL_FRONT_LEFT:
  350.       case GL_FRONT_AND_BACK:
  351.          if ( (*ctx->Driver.SetBuffer)( ctx, GL_FRONT ) == GL_FALSE ) {
  352.             gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
  353.             return;
  354.          }
  355.          ctx->Color.DrawBuffer = mode;
  356.          ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  357.      ctx->NewState |= NEW_RASTER_OPS;
  358.          break;
  359.       case GL_BACK:
  360.       case GL_BACK_LEFT:
  361.          if ( (*ctx->Driver.SetBuffer)( ctx, GL_BACK ) == GL_FALSE) {
  362.             gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
  363.             return;
  364.          }
  365.          ctx->Color.DrawBuffer = mode;
  366.          ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  367.      ctx->NewState |= NEW_RASTER_OPS;
  368.          break;
  369.       case GL_NONE:
  370.          ctx->Color.DrawBuffer = mode;
  371.          ctx->Buffer->Alpha = NULL;
  372.          ctx->NewState |= NEW_RASTER_OPS;
  373.          break;
  374.       case GL_FRONT_RIGHT:
  375.       case GL_BACK_RIGHT:
  376.       case GL_LEFT:
  377.       case GL_RIGHT:
  378.       case GL_AUX0:
  379.          gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  380.          break;
  381.       default:
  382.          gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
  383.    }
  384. }
  385.  
  386.  
  387.  
  388. void gl_ReadBuffer( GLcontext *ctx, GLenum mode )
  389. {
  390.    if (INSIDE_BEGIN_END(ctx)) {
  391.       gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  392.       return;
  393.    }
  394.    switch (mode) {
  395.       case GL_FRONT:
  396.       case GL_FRONT_LEFT:
  397.          if ( (*ctx->Driver.SetBuffer)( ctx, GL_FRONT ) == GL_FALSE) {
  398.             gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
  399.             return;
  400.          }
  401.          ctx->Pixel.ReadBuffer = mode;
  402.          ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  403.          ctx->NewState |= NEW_RASTER_OPS;
  404.          break;
  405.       case GL_BACK:
  406.       case GL_BACK_LEFT:
  407.          if ( (*ctx->Driver.SetBuffer)( ctx, GL_BACK ) == GL_FALSE) {
  408.             gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
  409.             return;
  410.          }
  411.          ctx->Pixel.ReadBuffer = mode;
  412.          ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  413.          ctx->NewState |= NEW_RASTER_OPS;
  414.          break;
  415.       case GL_FRONT_RIGHT:
  416.       case GL_BACK_RIGHT:
  417.       case GL_LEFT:
  418.       case GL_RIGHT:
  419.       case GL_AUX0:
  420.          gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  421.          break;
  422.       default:
  423.          gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
  424.    }
  425.  
  426.    /* Remember, the draw buffer is the default state */
  427.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  428. }
  429.  
  430.  
  431.  
  432.  
  433. void gl_Rectf( GLcontext *ctx, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
  434. {
  435.    if (INSIDE_BEGIN_END(ctx)) {
  436.       gl_error( ctx, GL_INVALID_OPERATION, "glRect" );
  437.       return;
  438.    }
  439.    (*ctx->API.Begin)( ctx, GL_QUADS );
  440.    (*ctx->API.Vertex4f)( ctx, x1, y1, 0.0F, 1.0F );
  441.    (*ctx->API.Vertex4f)( ctx, x2, y1, 0.0F, 1.0F );
  442.    (*ctx->API.Vertex4f)( ctx, x2, y2, 0.0F, 1.0F );
  443.    (*ctx->API.Vertex4f)( ctx, x1, y2, 0.0F, 1.0F );
  444.    (*ctx->API.End)( ctx );
  445. }
  446.  
  447.